package com.yst.webplugin.fieldhandler;

import com.yst.webplugin.annotation.HttpInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class FieldHandler {

    private final Field field;
    public FieldHandler(Field field){
        this.field=field;
    }
    public Field getField(){
        return field;
    }
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) {
        handle(field, request, response);
        return null;
    }

    private static List<Class<? extends IFieldHandler>> fieldHandlerList=new ArrayList<>();
    public synchronized static void register(Class<? extends IFieldHandler> fieldHandler){
        if (!fieldHandlerList.contains(fieldHandler)){
            fieldHandlerList.add(fieldHandler);
        }
    }

    public synchronized static void unregister(Class<? extends IFieldHandler> fieldHandler){
        fieldHandlerList.remove(fieldHandler);
    }

    public static boolean handle(Field field, HttpInfo httpInfo){
        for (Class<? extends IFieldHandler> fieldHandler:fieldHandlerList){
            try {
                IFieldHandler handler = fieldHandler.newInstance();
                if (handler.accept(field)) {
                    handler.handle(field, httpInfo);
                    return true;
                }
            }
            catch (Exception e){
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public static boolean handle(Field field, HttpServletRequest request, HttpServletResponse response){
        HttpInfo httpInfo=new HttpInfo(request,response);
        for (Class<? extends IFieldHandler> fieldHandler:fieldHandlerList){
            try {
                IFieldHandler handler = fieldHandler.newInstance();
                if (handler.accept(field)) {
                    handler.handle(field, httpInfo);
                    return true;
                }
            }
            catch (Exception e){
                httpInfo.writeThrowable(e);
                return true;
            }
        }
        return false;
    }

    static {
        register(CreateHandler.class);
        register(DeleteHandler.class);
        register(ModifyHandler.class);
        register(CommandHandler.class);
        register(QueryHandler.class);
        register(QueryTableHandler.class);
        register(BatchQueryHandler.class);
        register(BatchCommandHandler.class);
        register(GetModelByKeyHandler.class);
        register(QuerySingleRowHandler.class);
        register(BatchModelQueryHandler.class);
    }
}
